package com.cn.sl.server.common.dao.impl

import com.cn.sl.server.common.dao.BaseDao
import com.cn.sl.server.common.exception.EntityNotExistException
import com.cn.sl.server.common.model.BaseEntity
import com.cn.sl.server.common.repository.BaseRepository
import com.querydsl.core.BooleanBuilder
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Sort
import org.springframework.data.repository.findByIdOrNull

abstract class BaseDaoImpl<T : BaseEntity, R : BaseRepository<T>> : BaseDao<T, R> {
    override fun save(entity: T) {
        getRepository().save(entity)
    }

    override fun saveAll(entities: Collection<T>) {
        getRepository().saveAll(entities)
    }

    override fun findAllById(ids: Collection<Long>): List<T> {
        return getRepository().findAllById(ids)
    }

    override fun deleteById(id: Long) {
        getRepository().deleteById(id)
    }

    override fun deleteAllById(ids: List<Long>) {
        getRepository().deleteAllById(ids)
    }

    override fun delete(entity: T) {
        getRepository().delete(entity)
    }

    override fun findAll(): List<T> {
        return getRepository().findAll()
    }

    override fun deleteAll() {
        getRepository().deleteAll()
    }

    override fun deleteAll(entities: Collection<T>) {
        getRepository().deleteAll(entities)
    }

    override fun findAll(act: () -> BaseDao.PageQueryAct): Page<T> {
        val (booleanBuilder, page, pageSize, sort) = act()
        return getRepository().findAll(
            booleanBuilder,
            PageRequest.of(page - 1, pageSize, sort)
        )
    }

    override fun flush() {
        getRepository().flush()
    }

    override fun findAll(booleanBuilder: BooleanBuilder): List<T> {
        return getRepository().findAll(booleanBuilder).toList()
    }

    override fun findAll(booleanBuilder: BooleanBuilder, sort: Sort): List<T> {
        return getRepository().findAll(booleanBuilder, sort).toList()
    }

    override fun findAll(sort: Sort): List<T> {
        return getRepository().findAll(sort).toList()
    }

    override fun findById(id: Long): T {
        return getRepository().findByIdOrNull(id) ?: throw EntityNotExistException(id)
    }

    override fun findByIdOrNull(id: Long): T? {
        return getRepository().findByIdOrNull(id)
    }
}